package com.wsd.jing.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wsd.jing.dto.UserDTO;
import com.wsd.jing.entity.*;
import com.wsd.jing.mapper.MenuMapper;
import com.wsd.jing.mapper.UserMapper;
import com.wsd.jing.mapper.UserPostMapper;
import com.wsd.jing.mapper.UserRoleMapper;
import com.wsd.jing.request.CommonRequest;
import com.wsd.jing.service.IUserPostService;
import com.wsd.jing.service.IUserRoleService;
import com.wsd.jing.service.IUserService;
import com.wsd.jing.utils.SortUtil;
import com.wsd.jing.vo.MenuVO;
import com.wsd.jing.vo.UserInfoVO;
import com.wsd.jing.vo.UserVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.tom.com
 *
 * @author tom
 * @version 1.0.0
 * @projectName: jing
 * @packageName: com.wsd.jing.service.impl
 * @className: UserServiceImpl
 * @description: 用户服务实现类
 * @createDate 2022-11-14 07:02
 * @copyright 2022-11-14 07:02 www.tom.com Inc. All rights reserved.
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final UserMapper userMapper;
    private final MenuMapper menuMapper;
    private final UserRoleMapper userRoleMapper;
    private final UserPostMapper userPostMapper;
    private final IUserRoleService userRoleService;
    private final IUserPostService userPostService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertUser(UserDTO userDto) {
        // 保存用户
        User user = userDto.getUser();
        String password = SaSecureUtil.md5BySalt("Aa123456!", user.getAccount());
        user.setPassword(password);
        user.setCreateTime(LocalDateTime.now());
        this.save(user);

        // 保存用户角色
        List<UserRole> userRoleList = new ArrayList<>();
        userDto.getRoles().forEach(role -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(role);
            userRoleList.add(userRole);
        });
        userRoleService.saveBatch(userRoleList);

        // 保存用户职位
        List<UserPost> userPostList = new ArrayList<>();
        userDto.getPosts().forEach(post -> {
            UserPost userPost = new UserPost();
            userPost.setUserId(user.getId());
            userPost.setPostId(post);
            userPostList.add(userPost);
        });
        userPostService.saveBatch(userPostList);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUser(UserDTO userDto) {
        // 修改用户
        User user = userDto.getUser();
        user.setUpdateTime(LocalDateTime.now());
        this.updateById(user);

        // 修改用户角色
        QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.lambda().eq(UserRole::getUserId, user.getId());
        userRoleMapper.delete(userRoleQueryWrapper);

        List<UserRole> userRoleList = new ArrayList<>();
        userDto.getRoles().forEach(role -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(role);
            userRoleList.add(userRole);
        });
        userRoleService.saveBatch(userRoleList);

        // 修改用户职位
        QueryWrapper<UserPost> userPostQueryWrapper = new QueryWrapper<>();
        userPostQueryWrapper.lambda().eq(UserPost::getUserId, user.getId());
        userPostMapper.delete(userPostQueryWrapper);

        List<UserPost> userPostList = new ArrayList<>();
        userDto.getPosts().forEach(post -> {
            UserPost userPost = new UserPost();
            userPost.setUserId(user.getId());
            userPost.setPostId(post);
            userPostList.add(userPost);
        });
        userPostService.saveBatch(userPostList);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUser(Integer id) {
        // 删除用户角色
        QueryWrapper<UserPost> userPostQueryWrapper = new QueryWrapper<>();
        userPostQueryWrapper.lambda().eq(UserPost::getUserId, id);
        userPostMapper.delete(userPostQueryWrapper);

        // 删除用户职位
        QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.lambda().eq(UserRole::getUserId, id);
        userRoleMapper.delete(userRoleQueryWrapper);

        // 删除用户
        this.removeById(id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUsers(String ids) {
        List<String> idList = StrUtil.splitTrim(ids, ",");

        // 删除用户角色
        QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.lambda().in(UserRole::getUserId, idList);
        userRoleMapper.delete(userRoleQueryWrapper);

        // 删除用户职位
        QueryWrapper<UserPost> userPostQueryWrapper = new QueryWrapper<>();
        userPostQueryWrapper.lambda().in(UserPost::getUserId, idList);
        userPostMapper.delete(userPostQueryWrapper);

        //删除用户
        this.removeByIds(idList);
        return true;
    }

    @Override
    public UserVO getUser(Integer id) {
        // 用户信息
        User user = this.getById(id);

        // 用户角色信息
        QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.lambda().eq(UserRole::getUserId, id);
        List<Integer> userRoleList = userRoleMapper.selectList(userRoleQueryWrapper).stream().map(role -> role.getRoleId()).collect(Collectors.toList());

        // 用户职位信息
        QueryWrapper<UserPost> userPostQueryWrapper = new QueryWrapper<>();
        userPostQueryWrapper.lambda().eq(UserPost::getUserId, id);
        List<Integer> userPostList = userPostMapper.selectList(userPostQueryWrapper).stream().map(post -> post.getPostId()).collect(Collectors.toList());

        UserVO userDetailVO = new UserVO();
        userDetailVO.setUser(user);
        userDetailVO.setRoles(userRoleList);
        userDetailVO.setPosts(userPostList);
        return userDetailVO;
    }

    @Override
    public List<User> listUsers(CommonRequest commonRequest, User user) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // TODO 设置查询条件

        // 处理排序字段
        SortUtil.handleListSort(commonRequest, queryWrapper);
        return this.list(queryWrapper);
    }

    @Override
    public Map<String, Object> listPageUsers(CommonRequest commonRequest, User user) {
        Map<String, Object> resultMap = new HashMap<>(2);
        Page<User> page = new Page<>(commonRequest.getPageNum(), commonRequest.getPageSize());
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // TODO 设置查询条件
        if (StrUtil.isNotBlank(user.getName())) {
            queryWrapper.lambda().like(User::getName, user.getName());
        }
        if (StrUtil.isNotBlank(user.getAccount())) {
            queryWrapper.lambda().like(User::getAccount, user.getAccount());
        }
        if (StrUtil.isNotBlank(user.getMobile())) {
            queryWrapper.lambda().like(User::getMobile, user.getMobile());
        }
        if (ObjectUtil.isNotNull(user.getStatus())) {
            queryWrapper.lambda().eq(User::getStatus, user.getStatus());
        }
        if (user.getDepartmentId() != null) {
            queryWrapper.lambda().eq(User::getDepartmentId, user.getDepartmentId());
        }
        // 处理排序字段
        SortUtil.handlePageSort(commonRequest, page);
        IPage<User> result = this.page(page, queryWrapper);
        resultMap.put("rows", result.getRecords());
        resultMap.put("total", result.getTotal());
        return resultMap;
    }

    @Override
    public User getUserByAccount(String account) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", account);
        return this.getOne(queryWrapper);
    }

    @Override
    public UserInfoVO getUserInfo() {
        UserInfoVO userInfoVO = new UserInfoVO();
        Map<String, String> userInfo = new HashMap<>(2);
        List<MenuVO> menuVoList = new ArrayList<>();
        // 当前登录用户ID
        Integer userId = StpUtil.getLoginIdAsInt();

        // 查询用户基本信息
        User user = this.getById(userId);
        if (user != null) {
            userInfo.put("name", user.getName());
            userInfo.put("avatar", user.getAvatar());
        }

        // 查询用户菜单信息
        List<Menu> menuList = menuMapper.listMenus(userId);
        if (!menuList.isEmpty()) {
            menuVoList = convertTree(menuList, 1);
        }

        // 获取用户权限信息
        List<String> permissionList = StpUtil.getPermissionList();

        userInfoVO.setUserInfo(userInfo);
        userInfoVO.setPermissions(permissionList);
        userInfoVO.setMenus(menuVoList);
        return userInfoVO;
    }

    @Override
    public Boolean resetPassword(Integer id) {
        User user = this.getById(id);
        String password = SaSecureUtil.md5BySalt("Aa123456!", user.getAccount());
        user.setPassword(password);
        return this.updateById(user);
    }

    @Override
    public RolePermission getUserRolePermission(Integer id) {
        return userMapper.getUserRolePermission(id);
    }

    /**
     * @param menuList:菜单列表
     * @param pid:父级菜单ID
     * @return List<menuVo>
     * @author tom
     * @description 菜单转树结构
     * @createDate 2022/11/18 15:01
     */
    private List<MenuVO> convertTree(List<Menu> menuList, Integer pid) {
        List<MenuVO> result = new ArrayList<>();
        for (Menu menu : menuList) {
            Map<String, Object> metaMap = new HashMap<>(5);
            metaMap.put("icon", menu.getIcon());
            metaMap.put("title", menu.getMenuName());
            metaMap.put("isLink", menu.getLink());
            metaMap.put("isHidden", menu.getHidden());
            metaMap.put("isCached", menu.getCached());

            MenuVO menuVo = new MenuVO();
            menuVo.setPath(menu.getRoutePath());
            menuVo.setName(menu.getRouteName());
            menuVo.setComponent(menu.getRouteComponent());
            menuVo.setId(menu.getId());
            menuVo.setMeta(metaMap);

            Integer menuId = menu.getId();
            Integer parentId = menu.getParentId();
            if (parentId != null) {
                if (parentId.equals(pid)) {
                    //递归查询当前子菜单的子菜单
                    List<MenuVO> menuVoList = convertTree(menuList, menuId);
                    menuVo.setChildren(menuVoList);
                    result.add(menuVo);
                }
            }
        }
        return result;
    }
}
